/**
 ******************************************************************************
 * @file           : error_codes.c
 * @brief          : 错误处理工具实现
 ******************************************************************************
 * @attention
 *
 * 提供错误码转字符串、错误日志记录、错误统计等功能
 * 支持循环缓冲区日志，自动覆盖旧记录
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "error_codes.h"
#include "error_port.h"
#include <string.h>
#include <stdio.h>

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ERROR_COUNT_ARRAY_SIZE      256     /*!< 错误计数数组大小 */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

#if ERROR_LOG_ENABLED
static ErrorInfo_t sg_error_log[ERROR_LOG_MAX_ENTRIES];     /*!< 错误日志循环缓冲区 */
static uint8_t sg_error_log_index = 0;                      /*!< 错误日志当前索引 */
static uint32_t sg_error_count[ERROR_COUNT_ARRAY_SIZE];     /*!< 错误计数器数组 */
static uint32_t sg_total_error_count = 0;                   /*!< 总错误计数 */
#endif

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/**
 * @brief       将错误码转换为描述字符串
 *
 * @param[in]   code: 错误码
 *
 * @retval      const char*: 错误描述字符串
 *
 * @note        返回的字符串为常量字符串，不需要释放
 */
const char* Error_CodeToString(ErrorCode_t code)
{
    switch (code)
    {
        /* 成功 */
        case ERR_OK:
            return "OK";
        
        /* 参数错误 (1-19) */
        case ERR_NULL_POINTER:
            return "Null pointer";
        case ERR_INVALID_PARAM:
            return "Invalid parameter";
        case ERR_OUT_OF_RANGE:
            return "Out of range";
        case ERR_BUFFER_TOO_SMALL:
            return "Buffer too small";
        case ERR_INVALID_STATE:
            return "Invalid state";
        
        /* 资源错误 (20-39) */
        case ERR_NO_MEMORY:
            return "No memory";
        case ERR_NO_RESOURCE:
            return "No resource";
        case ERR_BUSY:
            return "Busy";
        case ERR_TIMEOUT:
            return "Timeout";
        case ERR_NOT_READY:
            return "Not ready";
        
        /* 操作错误 (40-59) */
        case ERR_NOT_INITIALIZED:
            return "Not initialized";
        case ERR_ALREADY_INITIALIZED:
            return "Already initialized";
        case ERR_NOT_SUPPORTED:
            return "Not supported";
        case ERR_PERMISSION_DENIED:
            return "Permission denied";
        case ERR_OVERFLOW:
            return "Overflow";
        case ERR_UNDERFLOW:
            return "Underflow";
        
        /* 硬件错误 (60-79) */
        case ERR_HARDWARE_FAULT:
            return "Hardware fault";
        case ERR_IO_ERROR:
            return "I/O error";
        case ERR_CRC_ERROR:
            return "CRC error";
        case ERR_CHECKSUM_ERROR:
            return "Checksum error";
        
        /* 通信错误 (80-99) */
        case ERR_COMM_ERROR:
            return "Communication error";
        case ERR_NO_RESPONSE:
            return "No response";
        case ERR_PROTOCOL_ERROR:
            return "Protocol error";
        
        /* ===== 基础外设 (100-199) ===== */
        
        /* UART模块错误 (100-119) */
        case ERR_UART_TIMEOUT:
            return "UART timeout";
        case ERR_UART_OVERRUN:
            return "UART overrun";
        case ERR_UART_FRAME_ERROR:
            return "UART frame error";
        case ERR_UART_PARITY_ERROR:
            return "UART parity error";
        
        /* I2C模块错误 (120-139) */
        case ERR_I2C_TIMEOUT:
            return "I2C timeout";
        case ERR_I2C_NACK:
            return "I2C NACK";
        case ERR_I2C_BUS_ERROR:
            return "I2C bus error";
        
        /* SPI模块错误 (140-159) */
        case ERR_SPI_TIMEOUT:
            return "SPI timeout";
        case ERR_SPI_BUSY:
            return "SPI busy";
        case ERR_SPI_CRC_ERROR:
            return "SPI CRC error";
        
        /* Timer模块错误 (160-179) */
        case ERR_TIMER_NOT_STARTED:
            return "Timer not started";
        case ERR_TIMER_OVERFLOW:
            return "Timer overflow";
        
        /* DMA模块错误 (180-199) */
        case ERR_DMA_TRANSFER_ERROR:
            return "DMA transfer error";
        case ERR_DMA_TIMEOUT:
            return "DMA timeout";
        case ERR_DMA_BUSY:
            return "DMA busy";
        
        /* ===== 存储设备 (200-299) ===== */
        
        /* EEPROM模块错误 (200-219) */
        case ERR_EEPROM_WRITE_FAIL:
            return "EEPROM write failed";
        case ERR_EEPROM_READ_FAIL:
            return "EEPROM read failed";
        case ERR_EEPROM_VERIFY_FAIL:
            return "EEPROM verify failed";
        case ERR_EEPROM_CORRUPTED:
            return "EEPROM corrupted";
        case ERR_EEPROM_TIMEOUT:
            return "EEPROM timeout";
        
        /* Flash模块错误 (220-239) */
        case ERR_FLASH_WRITE_FAIL:
            return "Flash write failed";
        case ERR_FLASH_ERASE_FAIL:
            return "Flash erase failed";
        case ERR_FLASH_PROTECTED:
            return "Flash protected";
        case ERR_FLASH_VERIFY_FAIL:
            return "Flash verify failed";
        
        /* SD卡模块错误 (240-259) */
        case ERR_SD_NOT_PRESENT:
            return "SD card not present";
        case ERR_SD_INIT_FAIL:
            return "SD card init failed";
        case ERR_SD_READ_FAIL:
            return "SD card read failed";
        case ERR_SD_WRITE_FAIL:
            return "SD card write failed";
        
        /* 文件系统错误 (260-279) */
        case ERR_FS_NOT_MOUNTED:
            return "File system not mounted";
        case ERR_FS_FILE_NOT_FOUND:
            return "File not found";
        case ERR_FS_WRITE_FAIL:
            return "File write failed";
        case ERR_FS_READ_FAIL:
            return "File read failed";
        case ERR_FS_NO_SPACE:
            return "No space left";
        
        /* ===== 高级外设 (300-399) ===== */
        
        /* ADC模块错误 (300-319) */
        case ERR_ADC_CONVERSION_FAIL:
            return "ADC conversion failed";
        case ERR_ADC_CALIBRATION_FAIL:
            return "ADC calibration failed";
        case ERR_ADC_TIMEOUT:
            return "ADC timeout";
        
        /* DAC模块错误 (320-339) */
        case ERR_DAC_OUTPUT_FAIL:
            return "DAC output failed";
        case ERR_DAC_CALIBRATION_FAIL:
            return "DAC calibration failed";
        
        /* RTC模块错误 (340-359) */
        case ERR_RTC_NOT_INITIALIZED:
            return "RTC not initialized";
        case ERR_RTC_INVALID_TIME:
            return "RTC invalid time";
        
        /* 显示模块错误 (360-379) */
        case ERR_DISPLAY_INIT_FAIL:
            return "Display init failed";
        case ERR_DISPLAY_TIMEOUT:
            return "Display timeout";
        
        /* ===== 通信协议 (400-459) ===== */
        
        /* CAN模块错误 (400-419) */
        case ERR_CAN_TIMEOUT:
            return "CAN timeout";
        case ERR_CAN_BUS_OFF:
            return "CAN bus off";
        case ERR_CAN_ERROR_WARNING:
            return "CAN error warning";
        case ERR_CAN_ERROR_PASSIVE:
            return "CAN error passive";
        
        /* USB模块错误 (420-439) */
        case ERR_USB_NOT_CONNECTED:
            return "USB not connected";
        case ERR_USB_TIMEOUT:
            return "USB timeout";
        case ERR_USB_TRANSFER_ERROR:
            return "USB transfer error";
        
        /* 网络模块错误 (440-459) */
        case ERR_NET_NOT_CONNECTED:
            return "Network not connected";
        case ERR_NET_TIMEOUT:
            return "Network timeout";
        case ERR_NET_DNS_FAIL:
            return "DNS failed";
        case ERR_NET_SOCKET_ERROR:
            return "Socket error";
        
        /* ===== 应用模块 (460+) ===== */
        
        /* 传感器模块错误 (460-479) */
        case ERR_SENSOR_FAULT:
            return "Sensor fault";
        case ERR_SENSOR_OUT_OF_RANGE:
            return "Sensor out of range";
        case ERR_SENSOR_TIMEOUT:
            return "Sensor timeout";
        
        /* 未知错误 */
        default:
            return "Unknown error";
    }
}

/**
 * @brief       获取错误码的严重级别
 *
 * @param[in]   code: 错误码
 *
 * @retval      ErrorSeverity_e: 错误严重级别
 *
 * @note        根据错误码范围判断严重级别
 *              - 0: 无错误
 *              - 1-19: 参数错误（编程错误，严重）
 *              - 20-39: 资源错误（可能临时性，警告）
 *              - 40-59: 操作错误（错误）
 *              - 60-79: 硬件错误（严重）
 *              - 80+: 其他错误（根据具体情况）
 */
ErrorSeverity_e Error_GetSeverity(ErrorCode_t code)
{
    if (code == ERR_OK)
    {
        return ERR_SEVERITY_NONE;
    }
    else if (code >= 1 && code < 20)
    {
        /* 参数错误 - 通常是编程错误，严重 */
        return ERR_SEVERITY_ERROR;
    }
    else if (code >= 20 && code < 40)
    {
        /* 资源错误 - 可能是临时性的，警告级别 */
        return ERR_SEVERITY_WARNING;
    }
    else if (code >= 40 && code < 60)
    {
        /* 操作错误 - 错误级别 */
        return ERR_SEVERITY_ERROR;
    }
    else if (code >= 60 && code < 80)
    {
        /* 硬件错误 - 严重级别 */
        return ERR_SEVERITY_CRITICAL;
    }
    else
    {
        /* 其他错误 - 默认错误级别 */
        return ERR_SEVERITY_ERROR;
    }
}

#if ERROR_LOG_ENABLED

/**
 * @brief       记录错误到日志
 *
 * @param[in]   code: 错误码
 * @param[in]   function: 发生错误的函数名
 * @param[in]   line: 发生错误的行号
 *
 * @retval      无
 *
 * @note        使用循环缓冲区记录错误历史
 *              当缓冲区满时，新记录会覆盖最旧的记录
 *              同时更新错误计数器
 */
void Error_Log(ErrorCode_t code, const char *function, uint32_t line)
{
    /* 记录错误信息到循环缓冲区 */
    sg_error_log[sg_error_log_index].code = code;
    sg_error_log[sg_error_log_index].function = function;
    sg_error_log[sg_error_log_index].line = line;
    sg_error_log[sg_error_log_index].timestamp = Error_Port_GetTick();
    
    /* 更新索引（循环） */
    sg_error_log_index = (sg_error_log_index + 1) % ERROR_LOG_MAX_ENTRIES;
    
    /* 更新错误计数器 */
    if (code < ERROR_COUNT_ARRAY_SIZE)
    {
        sg_error_count[code]++;
    }
    
    /* 更新总错误计数 */
    sg_total_error_count++;
}

/**
 * @brief       获取最后一次错误信息
 *
 * @param       无
 *
 * @retval      const ErrorInfo_t*: 指向最后一次错误信息的指针
 *
 * @note        返回的指针指向内部静态数据，不需要释放
 */
const ErrorInfo_t* Error_GetLastError(void)
{
    /* 计算最后一条记录的索引 */
    uint8_t last_index = (sg_error_log_index + ERROR_LOG_MAX_ENTRIES - 1) % ERROR_LOG_MAX_ENTRIES;
    return &sg_error_log[last_index];
}

/**
 * @brief       清除所有错误日志
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        清除日志缓冲区和所有错误计数器
 */
void Error_ClearLog(void)
{
    memset(sg_error_log, 0, sizeof(sg_error_log));
    memset(sg_error_count, 0, sizeof(sg_error_count));
    sg_error_log_index = 0;
    sg_total_error_count = 0;
}

/**
 * @brief       打印错误日志到调试输出
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        需要printf支持，用于调试
 *              遍历整个日志缓冲区，按时间顺序打印
 */
void Error_PrintLog(void)
{
    uint8_t i;
    char buffer[128];
    
    Error_Port_Print("\n==================== Error Log ====================\n");
    snprintf(buffer, sizeof(buffer), "Total errors: %lu\n", sg_total_error_count);
    Error_Port_Print(buffer);
    Error_Port_Print("---------------------------------------------------\n");
    
    /* 遍历日志缓冲区 */
    for (i = 0; i < ERROR_LOG_MAX_ENTRIES; i++)
    {
        if (sg_error_log[i].code != ERR_OK)
        {
            snprintf(buffer, sizeof(buffer), "[%lu ms] Error %d: %s\n",
                     sg_error_log[i].timestamp,
                     sg_error_log[i].code,
                     Error_CodeToString(sg_error_log[i].code));
            Error_Port_Print(buffer);
            
            snprintf(buffer, sizeof(buffer), "         at %s() line %lu\n",
                     sg_error_log[i].function,
                     sg_error_log[i].line);
            Error_Port_Print(buffer);
        }
    }
    
    Error_Port_Print("===================================================\n\n");
}

/**
 * @brief       获取特定错误码的出现次数
 *
 * @param[in]   code: 错误码
 *
 * @retval      uint32_t: 该错误码的出现次数
 *
 * @note        只统计错误码在有效范围内的次数
 */
uint32_t Error_GetCount(ErrorCode_t code)
{
    if (code >= 0 && code < ERROR_COUNT_ARRAY_SIZE)
    {
        return sg_error_count[code];
    }
    
    return 0;
}

/**
 * @brief       获取总错误次数
 *
 * @param       无
 *
 * @retval      uint32_t: 总错误次数
 */
uint32_t Error_GetTotalCount(void)
{
    return sg_total_error_count;
}

#else

/* 错误日志功能禁用时的空实现 */

void Error_Log(ErrorCode_t code, const char *function, uint32_t line)
{
    /* 空实现 */
    (void)code;
    (void)function;
    (void)line;
}

const ErrorInfo_t* Error_GetLastError(void)
{
    return NULL;
}

void Error_ClearLog(void)
{
    /* 空实现 */
}

void Error_PrintLog(void)
{
    /* 空实现 */
}

uint32_t Error_GetCount(ErrorCode_t code)
{
    (void)code;
    return 0;
}

uint32_t Error_GetTotalCount(void)
{
    return 0;
}

#endif /* ERROR_LOG_ENABLED */
